package com.mrjy.common.config;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mrjy.common.entity.UserInfo;
import com.mrjy.common.util.GlobalConstant;

@ServerEndpoint(value ="/userExpire",configurator=GetHttpSessionConfigurator.class)
public class WebSocket {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(WebSocket.class);
	
//	private static final Set<WebSocketTest1> onlineUsers =
//            new CopyOnWriteArraySet<WebSocketTest1>();
	private static ConcurrentHashMap<String, HttpSession> onlineUsers = new ConcurrentHashMap<String, HttpSession>();
	//concurrent包的线程安全Map，用来存放每个客户端对应的MyWebSocket对象。实现服务端与单一客户端通信的话，可以获取key，其中Key可以为用户标识httpSessionId
	private static ConcurrentHashMap<String, ArrayList<WebSocket>> simSessionWebSocketMap = new ConcurrentHashMap<String, ArrayList<WebSocket>>();
	//存放已登录用户列表key为userName  一对一
	private static ConcurrentHashMap<String, WebSocket> userSessionWebSocketMap = new ConcurrentHashMap<String, WebSocket>();
	
	private Session session;
	
	private HttpSession httpSession;
	
	@OnMessage
    public void onMessage(String message, EndpointConfig config){
//		System.out.println("Received: " + message);
		try {
//			session.getBasicRemote().sendText("This is an intermediate server message. Coun"+"---"+simSessionWebSocketMap.size());
			UserInfo userInfo = (UserInfo) this.httpSession.getAttribute(GlobalConstant.USER_INFO);
			if (userInfo != null) {
				ArrayList<WebSocket> clientSocketList;
			    if (simSessionWebSocketMap.get(this.httpSession.getId()) !=null) {
					clientSocketList = simSessionWebSocketMap.get(httpSession.getId());
					clientSocketList.add(this);
					simSessionWebSocketMap.replace(this.httpSession.getId(), clientSocketList);
				}else {
					clientSocketList = new ArrayList<WebSocket>();
					clientSocketList.add(this);
					simSessionWebSocketMap.put(this.httpSession.getId(), clientSocketList);
				}
			    
				String nickName = userInfo.getLoginCode();
				if (userSessionWebSocketMap.containsKey(nickName)) {
					WebSocket webSocket = userSessionWebSocketMap.get(nickName);
					//判断是否为同一个session
					if (webSocket != null && webSocket.httpSession!=null && !this.httpSession.getId().equals(webSocket.httpSession.getId())) {
						//用户重复登录
//System.out.println("多用户登陆"); 
						ArrayList<WebSocket> arrayList = simSessionWebSocketMap.get(webSocket.httpSession.getId());
						if (arrayList!=null) {
							for (WebSocket w : arrayList) {
								w.session.getBasicRemote().sendText("expire");
							}
						}
						
						webSocket.httpSession.invalidate();
						userSessionWebSocketMap.put(nickName, this);
					}else {
						userSessionWebSocketMap.replace(nickName, this);
					}
				}else {
					userSessionWebSocketMap.put(nickName, this);
				}
			}else {
				session.getBasicRemote().sendText("userInfo_error");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			LOGGER.info(e.getMessage());
		} catch (Exception e) {
			LOGGER.info(e.getMessage());
		}
	
    }
	
	@OnOpen
    public void onOpen (Session session,EndpointConfig ec) {
		this.session = session;
		this.httpSession = (HttpSession) ec.getUserProperties().get(HttpSession.class.getName());
//        System.out.println("Client connected:"+this.httpSession.getId());
    }

    @OnClose
    public void onClose () {
//    	System.out.println("Connection closed");
    	try {
			ArrayList<WebSocket> arrayList = simSessionWebSocketMap.get(this.httpSession.getId());
			if (arrayList != null && arrayList.size()!=0 && arrayList.contains(this)) {
				if (arrayList.size()>1) {
					arrayList.remove(this);
					simSessionWebSocketMap.replace(this.httpSession.getId(), arrayList);
				}else {
					if (this.httpSession != null) {
						UserInfo userInfo = (UserInfo) this.httpSession.getAttribute(GlobalConstant.USER_INFO);
						if (userInfo != null) {
							removeUserSessionWebSocketMap(userInfo.getLoginCode(),this.httpSession.getId());
						}
					}
					simSessionWebSocketMap.remove(this.httpSession.getId());
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			LOGGER.info(e.getMessage());
		}
    }
    
    /**
     * 根据 用户名key 和httpSessionId删除 用户名和Websocket的map
     * @param key
     * @param httpSessionId
     * @return
     */
    public static ConcurrentHashMap<String, WebSocket> removeUserSessionWebSocketMap(String key,String httpSessionId){
    	if (key!=null && userSessionWebSocketMap.containsKey(key) && userSessionWebSocketMap.get(key).httpSession.getId().equals(httpSessionId)) {
			userSessionWebSocketMap.remove(key);
		}
    	return userSessionWebSocketMap;
    }
    
    /**
     * 根据httpSessionId删除simSessionWebSocket中的值
     * @param httpSessionId
     * @return
     */
    public static ConcurrentHashMap<String, ArrayList<WebSocket>> removeSimSessionWebSocketMap(String httpSessionId){
    	if (httpSessionId != null && simSessionWebSocketMap.containsKey(httpSessionId)) {
			simSessionWebSocketMap.remove(httpSessionId);
		}
    	return simSessionWebSocketMap;
    }
    
    public static ConcurrentHashMap<String, WebSocket> getUserSessionWebSocketMap(){
    	return userSessionWebSocketMap;
    }
    
    /**
     * 添加登录用户的session
     * @param httpSessionId
     * @param session
     * @return
     */
    public static ConcurrentHashMap<String, HttpSession> addOnlineUserGroup(String httpSessionId,HttpSession session){
    	onlineUsers.put(httpSessionId, session);
    	return onlineUsers;
    }
    
    /**
     * 删除已登录的用户组的session
     * @param httpSessionId
     * @return
     */
    public static ConcurrentHashMap<String, HttpSession> removeOnlineUserGroup(String httpSessionId){
    	if (httpSessionId != null && onlineUsers.containsKey(httpSessionId)) {
			onlineUsers.remove(httpSessionId);
		}
    	return onlineUsers;
    }
    
    /**
     * 获取在线用户
     * @param httpSessionId
     * @return
     */
    public static HttpSession getOnlineUser(String httpSessionId){
    	if (httpSessionId!=null && onlineUsers.containsKey(httpSessionId)) {
    		return onlineUsers.get(httpSessionId);	
		}else {
			return null;
		}
    }
    
}
